home *** CD-ROM | disk | FTP | other *** search
/ Chip 2007 January, February, March & April / Chip-Cover-CD-2007-02.iso / Pakiet bezpieczenstwa / mini Pentoo LiveCD 2006.1 / mpentoo-2006.1.iso / livecd.squashfs / usr / lib / glibmm-2.4 / proc / pm / WrapParser.pm < prev   
Text File  |  2006-04-20  |  31KB  |  1,279 lines

  1. # gtkmm - WrapParser module
  2. #
  3. # Copyright 2001 Free Software Foundation
  4. #
  5. # This program is free software; you can redistribute it and/or modify
  6. # it under the terms of the GNU General Public License as published by
  7. # the Free Software Foundation; either version 2 of the License, or 
  8. # (at your option) any later version.
  9. #
  10. # This program is distributed in the hope that it will be useful,
  11. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the 
  13. # GNU General Public License for more details. 
  14. #
  15. # You should have received a copy of the GNU General Public License
  16. # along with this program; if not, write to the Free Software
  17. # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
  18. #
  19. package WrapParser;
  20. use strict;
  21. use warnings;
  22. use Util;
  23. use GtkDefs;
  24. use Function;
  25. use DocsParser;
  26.  
  27. BEGIN {
  28.      use Exporter   ();
  29.      our ($VERSION, @ISA, @EXPORT, @EXPORT_OK, %EXPORT_TAGS);
  30.  
  31.      # set the version for version checking
  32.      $VERSION     = 1.00;
  33.      @ISA         = qw(Exporter);
  34.      @EXPORT      = ( );
  35.      %EXPORT_TAGS = ( );
  36.      # your exported package globals go here,
  37.      # as well as any optionally exported functions
  38.      @EXPORT_OK   = ( );
  39.      }
  40. our @EXPORT_OK;
  41.  
  42. ############################################################################
  43.  
  44. my @tokens = ();
  45.  
  46. # $objWrapParser new($objOutputter)
  47. sub new($)
  48. {
  49.   my ($objOutputter) = @_;
  50.  
  51.   my $self = {};
  52.   bless $self;
  53.  
  54.    #Initialize member data:
  55.   $$self{objOutputter} = $objOutputter;
  56.   $$self{filename} = "(none)";
  57.   $$self{line_num} = 0;
  58.  
  59.   $$self{level} = 0;
  60.   $$self{class} = "";
  61.   $$self{c_class} = "";
  62.   $$self{in_class} = 0;
  63.   $$self{first_namespace} = 1;
  64.   $$self{namespace} = [];
  65.   $$self{in_namespace} = [];
  66.  
  67.   $$self{defsdir} = ".";
  68.  
  69.   $$self{module} = ""; #e.g. "gtkmm"
  70.  
  71.   $$self{type} = "GTKOBJECT"; # or "BOXEDTYPE", or "GOBJECT" - wrapped differently.
  72.  
  73.   return $self;
  74. }
  75.  
  76. # void parse_and_build_output()
  77. sub parse_and_build_output($)
  78. {
  79.   my ($self) = @_;
  80.  
  81.   my $objOutputter = $$self{objOutputter};
  82.  
  83.   # Parse the tokens.
  84.   my $token;
  85.   while ( scalar(@tokens) )
  86.   {
  87.     $token = $self->extract_token();
  88.     my $bAppend = 1;
  89.  
  90.     # we need to monitor the depth of braces
  91.     if ($token eq '{')         { $self->on_open_brace(); }
  92.     if ($token eq '}')         { $self->on_close_brace(); $bAppend = 0;}
  93.  
  94.     # protect `' from the source file from m4
  95.     if ($token eq "`")         { $objOutputter->append("`'__BT__`'"); next; }
  96.     if ($token eq "'")         { $objOutputter->append("`'__FT__`'"); next; }
  97.  
  98.     if ($token eq '"')         { $objOutputter->append($self->on_string_literal()); next; }
  99.     if ($token eq '//')        { $objOutputter->append($self->on_comment_cpp()); next; }
  100.     if ($token eq '/*')        { $objOutputter->append($self->on_comment_c()); next; }
  101.  
  102.     # handle #m4begin ... #m4end
  103.     if ($token eq "#m4begin")  { $objOutputter->append($self->on_m4_section()); next;}
  104.  
  105.     # handle #m4 ... \n
  106.     if ($token eq "#m4")       { $objOutputter->append($self->on_m4_line()); next;}
  107.  
  108.     if ($token eq "_DEFS")     { $self->on_defs(); next;} #Read the defs file.
  109.     if ($token eq "_IGNORE")     { $self->on_ignore(); next;} #Ignore a function.
  110.     if ($token eq "_IGNORE_SIGNAL")     { $self->on_ignore_signal(); next;} #Ignore a signal.
  111.     if ($token eq "_WRAP_METHOD")     { $self->on_wrap_method(); next;}
  112.     if ($token eq "_WRAP_METHOD_DOCS_ONLY")     { $self->on_wrap_method_docs_only(); next;}
  113.     if ($token eq "_WRAP_CORBA_METHOD")     { $self->on_wrap_corba_method(); next;} #Used in libbonobo*mm.
  114.     if ($token eq "_WRAP_SIGNAL") { $self->on_wrap_signal(); next;}
  115.     if ($token eq "_WRAP_PROPERTY") { $self->on_wrap_property(); next;}
  116.     if ($token eq "_WRAP_VFUNC") { $self->on_wrap_vfunc(); next;}
  117.     if ($token eq "_WRAP_CTOR")   { $self->on_wrap_ctor(); next;}
  118.     if ($token eq "_WRAP_CREATE") { $self->on_wrap_create(); next;}
  119.  
  120.     if ($token eq "_WRAP_ENUM")   { $self->on_wrap_enum(); next;}
  121.     if ($token eq "_WRAP_GERROR") { $self->on_wrap_gerror(); next;}
  122.  
  123.     my $prefix_class = "_CLASS_"; # e.g. _CLASS_GTKOBJECT
  124.     my $token_prefix = substr($token, 0, length($prefix_class));
  125.     if ($token_prefix eq $prefix_class)
  126.     {
  127.       $self->on_class($token);
  128.       next;
  129.  
  130.       # e.g.:
  131.       # _CLASS_GENERIC
  132.       # _CLASS_GOBJECT
  133.       # _CLASS_GTKOBJECT
  134.       # _CLASS_BOXEDTYPE
  135.       # _CLASS_BOXEDTYPE_STATIC
  136.       # _CLASS_INTERFACE
  137.       # _CLASS_OPAQUE_COPYABLE
  138.       # _CLASS_OPAQUE_REFCOUNTED
  139.     }
  140.  
  141.     if ($token eq "namespace") { $self->on_namespace() };
  142.  
  143.     # After all token manipulations
  144.     if($bAppend)
  145.     {
  146.       $objOutputter->append($token);
  147.     }
  148.   }
  149. }
  150.  
  151. sub error($$)
  152. {
  153.   my ($self, $format) = @_;
  154.  
  155.   $format = "$$self{filename}:$$self{line_num}: $format";
  156.   printf STDERR $format,@_;
  157. }
  158.  
  159. ######################################################################
  160. ##### 1.1 parser subroutines
  161.  
  162. ########################################
  163. ###  returns the next token, ignoring some stuff.
  164. # $string extract_token()
  165. sub extract_token($)
  166. {
  167.   my ($self) = @_;
  168.  
  169.   while ( scalar(@tokens) )
  170.   {
  171.     $_ = shift @tokens;
  172.  
  173.     # skip empty tokens
  174.     next if ( !defined($_) or $_ eq "" );
  175.  
  176.     # eat line statements. TODO: e.g.?
  177.     if ( /^#l (\S+)\n/)
  178.     {
  179.       $$self{line_num} = $1;
  180.       next;
  181.     }
  182.  
  183.     # eat file statements. TODO: e.g.?
  184.     if ( /^#f (\S+)\n/)
  185.     {
  186.       $$self{filename} = $1;
  187.       next;
  188.     }
  189.  
  190.     return $_;
  191.    }
  192.      
  193.   return "";
  194. }
  195.  
  196. # bool tokens_remaining()
  197. sub tokens_remaining($)
  198. {
  199.   my ($self) = @_;
  200.   return scalar(@tokens)!=0;
  201. }
  202.  
  203.  
  204. ########################################
  205. ###  we pass strings literally with quote substitution
  206. # void on_string_literal()
  207. sub on_string_literal($)
  208. {
  209.   my ($self) = @_;
  210.  
  211.   my @out;
  212.   push (@out, '"');
  213.   while ( scalar(@tokens) )
  214.   {
  215.     $_ = $self->extract_token();
  216.     if ($_ eq "`") { push(@out, "`'__BT__`'"); next; }
  217.     if ($_ eq "'") { push(@out, "`'__FT__`'"); next; }
  218.     push (@out, $_);
  219.  
  220.     return join("",@out) if ($_ eq '"');
  221.   }
  222.  
  223.   my $line_num = $$self{line_num};
  224.   my $filename = $$self{filename};
  225.   print STDERR "$filename:$line_num: Hit eof while in string\n";
  226. }
  227.  
  228.  
  229. ########################################
  230. ###  we pass comments literally with quote substitution
  231. # void on_comment_cpp()
  232. sub on_comment_cpp($)
  233. {
  234.   my ($self) = @_;
  235.  
  236.   my @out;
  237.   push (@out,"//\`");
  238.   while ( scalar(@tokens) )
  239.   {
  240.     $_ = $self->extract_token();
  241.     if ($_ eq "`") { push(@out,"\'__BT__\`"); next; }
  242.     if ($_ eq "'") { push(@out,"\'__FT__\`"); next; }
  243.     if ($_ eq "\n")
  244.     {
  245.       push (@out,"\'\n");
  246.       return join("",@out)
  247.     }
  248.  
  249.     if ($_ =~ /^_[A-Z]+$/) {$_="_$_";}  # wipe out potential macros
  250.  
  251.     push (@out,$_);
  252.   }
  253. }
  254.  
  255.  
  256. ########################################
  257. ###  we pass C comments literally with quote substitution
  258. # void on_comment_c()
  259. sub on_comment_c($)
  260. {
  261.   my ($self) = @_;
  262.  
  263.   my @out;
  264.   push (@out,"/*\`");
  265.   while ( scalar(@tokens) )
  266.   {
  267.     $_ = $self->extract_token();
  268.     if ($_ eq "`") { push(@out,"\'__BT__\`"); next; }
  269.     if ($_ eq "'") { push(@out,"\'__FT__\`"); next; }
  270.     if ($_ eq "*/")
  271.     {
  272.       push (@out,"\'*/");
  273.       return join("",@out)
  274.     }
  275.  
  276.     push (@out,$_);
  277.   }
  278. }
  279.  
  280.  
  281. ########################################
  282. ###  handle #m4begin ... #m4end
  283. # we don't substitute ` or ' in #m4begin
  284. # void on_m4_section()
  285. sub on_m4_section($)
  286. {
  287.   my ($self) = @_;
  288.  
  289.   my @value;
  290.   my $token;
  291.  
  292.   while ( scalar(@tokens) )
  293.   {
  294.     $token = $self->extract_token();
  295.     return join("", @value) if ($token eq "#m4end");
  296.     push(@value, $token);
  297.   }
  298.  
  299.   my $line_num = $$self{line_num};
  300.   my $filename = $$self{filename};
  301.   print STDERR "$filename:$line_num: Hit eof looking for #m4end\n";
  302.   next;
  303. }
  304.  
  305.  
  306. ########################################
  307. ###  handle #m4 ... /n
  308. # we don't substitute ` or ' in #m4
  309. # void on_m4_line()
  310. sub on_m4_line ($)
  311. {
  312.   my ($self) = @_;
  313.  
  314.   my @value;
  315.   my $token;
  316.   while ( scalar(@tokens) )
  317.   {
  318.     $token = $self->extract_token();
  319.     push(@value,$token); # push first, so we don't eat the newline
  320.     return join("",@value) if ($token eq "\n");
  321.   }
  322. }
  323.  
  324.  
  325. ########################################
  326. # m4 needs to know when we entered a namespace
  327. # void on_namespace()
  328. sub on_namespace($)
  329. {
  330.   my ($self) = @_;
  331.   my $objOutputter = $$self{objOutputter};
  332.  
  333.   my $number = 0;
  334.   my $token;
  335.   my $arg;
  336.  
  337.   # we need to peek ahead to figure out what type of namespace 
  338.   # declaration this is.
  339.   while ( $number < scalar(@tokens) )
  340.   {
  341.     $token = $tokens[$number];
  342.     $number++;
  343.     next if (!defined($token) or $token eq "");
  344. #      print "> $token\n";
  345.  
  346.     if ($token eq '{')
  347.     {
  348.       $arg = string_trim($arg);
  349.  
  350.       if ($$self{first_namespace})
  351.       {
  352.         $objOutputter->append("_SECTION(SECTION_HEADER2)\n");
  353.         $$self{first_namespace} = 0;
  354.       }
  355.  
  356.       $objOutputter->append("_NAMESPACE($arg)");
  357.       unshift(@{$$self{namespace}}, $arg);
  358.       unshift(@{$$self{in_namespace}}, $$self{level}+1);
  359.       return;
  360.     }
  361.  
  362.     next if ( $token =~ /^#[lf] \S+\n/);
  363.     return if ($token eq ';');
  364.  
  365.     $arg .= $token; #concatenate
  366.   }
  367. }
  368.  
  369.  
  370. ########################################
  371. ###  we don't want to report every petty function as unwrapped
  372. # void on_ignore($)
  373. sub on_ignore($)
  374. {
  375.   my ($self) = @_;
  376.   my $str = $self->extract_bracketed_text();
  377.   my @args = split(/\s+|,/,$str);
  378.   foreach (@args)
  379.   {
  380.     next if ($_ eq "");
  381.     GtkDefs::lookup_function($_); #Pretend that we've used it.
  382.   }
  383. }
  384.  
  385. sub on_ignore_signal($)
  386. {
  387.   my ($self) = @_;
  388.   my $str = $self->extract_bracketed_text();
  389.   $str = string_trim($str);
  390.   $str = string_unquote($str);
  391.   my @args = split(/\s+|,/,$str);
  392.   foreach (@args)
  393.   {
  394.     next if ($_ eq "");
  395.     GtkDefs::lookup_signal($$self{c_class}, $_); #Pretend that we've used it.
  396.   }
  397. }
  398.  
  399. ########################################
  400. ###  we have certain macros we need to insert at end of statements
  401. # void on_class($, $strClassCommand)
  402. sub on_class($$)
  403. {
  404.   my ($self, $class_command) = @_;
  405.  
  406.   my $objOutputter = $$self{objOutputter};
  407.  
  408.   $$self{in_class} = $$self{level};
  409.  
  410.   #Remember the type of wrapper required, so that we can append the correct _END_CLASS_* macro later.
  411.   { 
  412.     my $str = $class_command;
  413.     $str =~ s/^_CLASS_//;
  414.     $$self{type} = $str;
  415.   }
  416.  
  417.   my $str = $self->extract_bracketed_text();
  418.   my ($class, $c_class) = split(',',$str);
  419.   $class = string_trim($class);
  420.   $c_class = string_trim($c_class);
  421.  
  422.   $$self{class} = $class;
  423.   $$self{c_class} = $c_class;
  424.  
  425.   my @back;
  426.   push(@back, $class_command);
  427.   push(@back, "($str)");
  428.   
  429.   # When we hit _CLASS, we walk backwards through the output to find "class"
  430.   my $token;
  431.   while ( scalar(@{$$objOutputter{out}}) > 0)
  432.   {
  433.     $token = pop @{$$objOutputter{out}};
  434.     unshift(@back, $token);
  435.     if ($token eq "class")
  436.     {
  437.       $objOutputter->append("_CLASS_START()");
  438.  
  439.       my $strBack = join("", @back);
  440.  
  441.       $objOutputter->append($strBack);
  442.       return;
  443.     }
  444.   }
  445.  
  446.   $self->error("$class_command outside of class.\n");
  447.   exit(-1);
  448. }
  449.  
  450.  
  451. # order to read the defs file
  452. # void on_defs()
  453. sub on_defs($)
  454. {
  455.   my ($self) = @_;
  456.  
  457.   my $str = $self->extract_bracketed_text();
  458.   my ($module, $defsfile) = split(/,/, $str); #e.g. _DEFS(gtkmm,gtk), where gtkmm is the module name, and gtk is the defs file name.
  459.   # $$self{section} = $section;  #Save it so that we can reuse it in read_defs_included.
  460.   $$self{module} = $module; #Use it later in call to output_temp_g1().
  461.  
  462.   GtkDefs::read_defs("$$self{defsdir}", "$defsfile.defs");
  463.  
  464.   #Read the documentation too, so that we can merge it into the generated C++ code:
  465.   my $docs_filename = $defsfile . "_docs.xml";
  466.   my $docs_filename_override = $defsfile . "_docs_override.xml";
  467.   DocsParser::read_defs("$$self{defsdir}", $docs_filename, $docs_filename_override);
  468. }
  469.  
  470. # void on_open_brace()
  471. sub on_open_brace($)
  472. {
  473.   my ($self) = @_;
  474.  
  475.   $$self{level}++;
  476. }
  477.  
  478. # void on_close_brace($)
  479. sub on_close_brace($)
  480. {
  481.   my ($self) = @_;
  482.   my $objOutputter = $$self{objOutputter};
  483.  
  484.   #push(@out, "($$self{level})");
  485.  
  486.   $self->on_end_class()
  487.     if ($$self{in_class} && $$self{in_class} == $$self{level});
  488.  
  489.   $objOutputter->append("}"); #We append it here instead of after we return, so that we can end the namespace after it.
  490.  
  491.   $self->on_end_namespace()
  492.     if ( (scalar(@{$$self{in_namespace}}) > 0) && (@{$$self{in_namespace}}[0] == $$self{level}) );
  493.  
  494.   $$self{level}--;
  495. }
  496.  
  497.  
  498. ########################################
  499. ###  denote the end of a class
  500. # void on_end_class($)
  501. sub on_end_class($)
  502. {
  503.   my ($self) = @_;
  504.   my $objOutputter = $$self{objOutputter};
  505.  
  506.   # Examine $$self{type}, which was set in on_class()
  507.   # And append the _END_CLASS_* macro, which will, in turn, output the m4 code.
  508.   {
  509.     my $str = $$self{type};
  510.     $objOutputter->append("`'_END_CLASS_$str()\n");
  511.   }
  512.  
  513.   $$self{class} = "";
  514.   $$self{c_class} = "";
  515.   $$self{in_class} = 0;
  516. }
  517.  
  518.  
  519. ########################################
  520. ###  
  521. # void on_end_namespace($)
  522. sub on_end_namespace($)
  523. {
  524.   my ($self) = @_;
  525.   my $objOutputter = $$self{objOutputter};
  526.  
  527.   $objOutputter->append("`'_END_NAMESPACE()");
  528.   shift( @{$$self{namespace}} );
  529.   shift( @{$$self{in_namespace}} );
  530. }
  531.  
  532.  
  533. ######################################################################
  534. ##### some utility subroutines
  535.  
  536. ########################################
  537. ###  takes (\S+) from the tokens (smart)
  538. # $string extract_bracketed_text()
  539. sub extract_bracketed_text($)
  540. {
  541.   my ($self) = @_;
  542.  
  543.   my $level = 1;
  544.   my $str = "";
  545.  
  546.   # Move to the first "(":
  547.   while ( scalar(@tokens) )
  548.     {
  549.       my $t = $self->extract_token();
  550.       last if ($t eq "(");
  551.     }
  552.  
  553.   # Concatenate until the corresponding ")":
  554.   while ( scalar(@tokens) )
  555.     {
  556.       my $t = $self->extract_token();
  557.       $level++ if ($t eq "(");
  558.       $level-- if ($t eq ")");
  559.  
  560.       return $str if (!$level);
  561.       $str .= $t;
  562.     }
  563.  
  564.   return "";
  565. }
  566.  
  567.  
  568. ########################################
  569. ###  breaks up a string by commas (smart)
  570. # @strings string_split_commas($string)
  571. sub string_split_commas($)
  572. {
  573.   my ($in) = @_;
  574.  
  575.   my @out;
  576.   my $level = 0;
  577.   my $str = "";
  578.   my @in = split(/([,()])/, $in);
  579.  
  580.   while ($#in > -1)
  581.     {
  582.       my $t = shift @in;
  583.  
  584.       next if ($t eq "");
  585.       $level++ if ($t eq "(");
  586.       $level-- if ($t eq ")");
  587.  
  588.       # skip , inside functions  Ie.  void (*)(int,int)
  589.       if ( ($t eq ",") && !$level) 
  590.         {
  591.           push(@out, $str);
  592.           $str="";
  593.           next;
  594.         }
  595.  
  596.       $str .= $t;
  597.     }
  598.  
  599.   push(@out,$str);
  600.   return @out;
  601. }
  602.  
  603.  
  604. ########################################
  605. ###  reads in the preprocessor files
  606. # we insert line and file directives for later stages
  607. # void read_file()
  608. sub read_file($$$)
  609. {
  610.   my ($self, $srcdir, $source) = @_;
  611.  
  612.   my $line;
  613.   my @in;
  614.  
  615.   if ( ! -r "${srcdir}/${source}.hg")
  616.   {
  617.     print "Unable to find header file $srcdir/$source.hg\n";
  618.     exit(-1); 
  619.   }
  620.  
  621.   # Read header file:
  622.   open(FILE, "${srcdir}/${source}.hg");
  623. #  push(@in, "#f ${source}.hg\n"); #TODO: What does #f do?
  624.   $line = 1;
  625.   while (<FILE>)
  626.     {
  627. #      push(@in, "#l $line\n"); #TODO: What does #l do?
  628.       push(@in, $_);
  629.       $line++;
  630.     }
  631.   close(FILE);
  632.   push(@in, "\n_SECTION(SECTION_SRC_CUSTOM)\n");
  633.  
  634.   # Source file is optional.
  635.   if ( -r "${srcdir}/${source}.ccg")
  636.   {
  637.     open(FILE, "${srcdir}/${source}.ccg");
  638.     $line = 1;
  639. #    push(@in, "#f ${source}.ccg\n"); #TODO: What does #f do?
  640.     while (<FILE>)
  641.       {
  642. #        push(@in, "#l $line\n"); #TODO: What does #l do?
  643.         push(@in, $_);
  644.         $line++;
  645.       }
  646.     close(FILE);
  647.   }
  648.  
  649.   my $strIn = join("", @in);
  650.  
  651.   # Break the file into tokens.  Token is
  652.   #      any group of #, A to z, 0 to 9, _
  653.   #      /*
  654.   #      *.
  655.   #      //
  656.   #      any char proceeded by \
  657.   #      symbols ;{}"`'()
  658.   #      newline
  659.   @tokens = split(/(\#[lf] \S+\n)|([#A-Za-z0-9_]+)|(\/\*)|(\*\/)|(\/\/)|(\\.)|([;{}"'`()])|(\n)/,
  660.                          $strIn);
  661. }
  662.  
  663.  
  664. sub class_prefix($)
  665. {
  666.   my ($self) = @_;
  667.  
  668.   my $str = $$self{class};
  669.   $str =~ s/([a-z])([A-Z])/$1_$2/g;
  670.   $str =~ tr/A-Z/a-z/;
  671.   return $str;
  672. }
  673.  
  674.  
  675. ######################################################################
  676. ##### 2.1 subroutines for _WRAP
  677.  
  678. ########################################
  679.  
  680. # $bool check_for_eof()
  681. sub check_for_eof($)
  682. {
  683.   my ($self) = @_;
  684.  
  685.   my $filename = $$self{filename};
  686.   my $line_num = $$self{line_num};
  687.  
  688.   if (!(scalar(@tokens)))
  689.   {
  690.     print STDERR "$filename:$line_num:hit eof in _WRAP\n";
  691.     return 0; #EOF
  692.   }
  693.  
  694.   return 1; # No EOF
  695. }
  696.  
  697. # void on_wrap_method()
  698. sub on_wrap_method($)
  699. {
  700.   my ($self) = @_;
  701.   my $objOutputter = $$self{objOutputter};
  702.  
  703.   if( !($self->check_for_eof()) )
  704.   {
  705.    return;
  706.   }
  707.  
  708.   my $filename = $$self{filename};
  709.   my $line_num = $$self{line_num};
  710.  
  711.   my $str = $self->extract_bracketed_text();
  712.   my @args = string_split_commas($str);
  713.  
  714.   my $entity_type = "method";
  715.  
  716.   if (!$$self{in_class})
  717.     {
  718.       print STDERR "$filename:$line_num:_WRAP macro encountered outside class\n";
  719.       return;
  720.     }
  721.  
  722.   my $objCfunc;
  723.   my $objCppfunc;
  724.  
  725.   # handle first argument
  726.   my $argCppMethodDecl = $args[0];
  727.   if ($argCppMethodDecl =~ /^\S+$/ ) #Checks that it's not empty and that it contains no whitespace.
  728.   {
  729.     print STDERR "$filename:$line_num:_WRAP can't handle unspecified method $argCppMethodDecl\n";
  730.     return;
  731.   }
  732.   else
  733.   {
  734.     #Parse the method decaration and build an object that holds the details:
  735.     $objCppfunc = &Function::new($argCppMethodDecl, $self);
  736.   }
  737.  
  738.  
  739.   # handle second argument:
  740.  
  741.   my $argCFunctionName = $args[1];
  742.   $argCFunctionName = string_trim($argCFunctionName);
  743.  
  744.   #Get the c function's details:
  745.  
  746.   #Checks that it's not empty and that it contains no whitespace.
  747.   if ($argCFunctionName =~ /^\S+$/ )
  748.   {
  749.     #c-name. e.g. gtk_clist_set_column_title
  750.     $objCfunc = GtkDefs::lookup_function($argCFunctionName);
  751.  
  752.     if(!$objCfunc) #If the lookup failed:
  753.     {
  754.       $objOutputter->output_wrap_failed($argCFunctionName, "method defs lookup failed (1)");
  755.       return;
  756.     }
  757.   }
  758.  
  759.   # Extra ref needed?
  760.   while(scalar(@args) > 2) # If the optional ref/err arguments are there.
  761.   {
  762.     my $argRef = string_trim(pop @args);
  763.     if($argRef eq "refreturn")
  764.     {
  765.       $$objCfunc{rettype_needs_ref} = 1;
  766.     }
  767.       if($argRef eq "errthrow")
  768.     {
  769.       $$objCfunc{throw_any_errors} = 1;
  770.     }
  771.   }
  772.    
  773.   my $commentblock = "";
  774.   $commentblock = DocsParser::lookup_documentation($argCFunctionName);
  775.  
  776.   $objOutputter->output_wrap_meth($filename, $line_num, $objCppfunc, $objCfunc, $argCppMethodDecl, $commentblock);
  777. }
  778.  
  779. # void on_wrap_method_docs_only()
  780. sub on_wrap_method_docs_only($)
  781. {
  782.   my ($self) = @_;
  783.   my $objOutputter = $$self{objOutputter};
  784.  
  785.   if( !($self->check_for_eof()) )
  786.   {
  787.    return;
  788.   }
  789.  
  790.   my $filename = $$self{filename};
  791.   my $line_num = $$self{line_num};
  792.  
  793.   my $str = $self->extract_bracketed_text();
  794.   my @args = string_split_commas($str);
  795.  
  796.   my $entity_type = "method";
  797.  
  798.   if (!$$self{in_class})
  799.     {
  800.       print STDERR "$filename:$line_num:_WRAP macro encountered outside class\n";
  801.       return;
  802.     }
  803.  
  804.   my $objCfunc;
  805.  
  806.   # handle first argument
  807.   my $argCFunctionName = $args[0];
  808.   $argCFunctionName = string_trim($argCFunctionName);
  809.  
  810.   #Get the c function's details:
  811.   
  812.   #Checks that it's not empty and that it contains no whitespace.
  813.   if ($argCFunctionName =~ /^\S+$/ ) 
  814.   {
  815.     #c-name. e.g. gtk_clist_set_column_title
  816.     $objCfunc = GtkDefs::lookup_function($argCFunctionName);
  817.  
  818.     if(!$objCfunc) #If the lookup failed:
  819.     {
  820.       $objOutputter->output_wrap_failed($argCFunctionName, "method defs lookup failed (1)");
  821.       return;
  822.     }
  823.   }
  824.  
  825.   # Extra ref needed?
  826.   while(scalar(@args) > 1) # If the optional ref/err arguments are there.
  827.   {
  828.     my $argRef = string_trim(pop @args);
  829.     if($argRef eq "errthrow")
  830.     {
  831.       $$objCfunc{throw_any_errors} = 1;
  832.     }
  833.   }
  834.  
  835.   my $commentblock = "";
  836.   $commentblock = DocsParser::lookup_documentation($argCFunctionName);
  837.  
  838.   $objOutputter->output_wrap_meth_docs_only($filename, $line_num, $commentblock);
  839. }
  840.  
  841. sub on_wrap_ctor($)
  842. {
  843.   my ($self) = @_;
  844.   my $objOutputter = $$self{objOutputter};
  845.  
  846.   if( !($self->check_for_eof()) )
  847.   {
  848.    return;
  849.   }
  850.  
  851.   my $filename = $$self{filename};
  852.   my $line_num = $$self{line_num};
  853.  
  854.   my $str = $self->extract_bracketed_text();
  855.   my @args = string_split_commas($str);
  856.  
  857.   my $entity_type = "method";
  858.  
  859.   if (!$$self{in_class})
  860.     {
  861.       print STDERR "$filename:$line_num:_WRAP_CTOR macro encountered outside class\n";
  862.       return;
  863.     }
  864.  
  865.   my $objCfunc;
  866.   my $objCppfunc;
  867.  
  868.   # handle first argument
  869.   my $argCppMethodDecl = $args[0];
  870.   if ($argCppMethodDecl =~ /^\S+$/ ) #Checks that it's not empty and that it contains no whitespace.
  871.     {
  872.       print STDERR "$filename:$line_num:_WRAP_CTOR can't handle unspecified method $argCppMethodDecl\n";
  873.       return;
  874.     }
  875.   else
  876.     {
  877.       #Parse the method decaration and build an object that holds the details:
  878.       $objCppfunc = &Function::new_ctor($argCppMethodDecl, $self);
  879.     }
  880.  
  881.  
  882.   # handle second argument:
  883.  
  884.   my $argCFunctionName = $args[1];
  885.   $argCFunctionName = string_trim($argCFunctionName);
  886.  
  887.   #Get the c function's details:
  888.   if ($argCFunctionName =~ /^\S+$/ ) #Checks that it's not empty and that it contains no whitespace.
  889.   {
  890.     $objCfunc = GtkDefs::lookup_function($argCFunctionName); #c-name. e.g. gtk_clist_set_column_title
  891.     if(!$objCfunc) #If the lookup failed:
  892.     {
  893.       $objOutputter->output_wrap_failed($argCFunctionName, "ctor defs lookup failed (2)");
  894.       return;
  895.     }
  896.   }
  897.  
  898.   $objOutputter->output_wrap_ctor($filename, $line_num, $objCppfunc, $objCfunc, $argCppMethodDecl);
  899. }
  900.  
  901. sub on_wrap_create($)
  902. {
  903.   my ($self) = @_;
  904.  
  905.   if( !($self->check_for_eof()) )
  906.   {
  907.     return;
  908.   }
  909.  
  910.   my $str = $self->extract_bracketed_text();
  911.  
  912.   my $objOutputter = $$self{objOutputter};
  913.   $objOutputter->output_wrap_create($str, $self);
  914. }
  915.  
  916. sub on_wrap_signal($)
  917. {
  918.   my ($self) = @_;
  919.  
  920.   if( !($self->check_for_eof()) )
  921.   {
  922.     return;
  923.   }
  924.  
  925.   my $str = $self->extract_bracketed_text();
  926.   my @args = string_split_commas($str);
  927.  
  928.   #Get the arguments:
  929.   my $argCppDecl = $args[0];
  930.   my $argCName = $args[1];
  931.   $argCName = string_trim($argCName);
  932.   $argCName = string_unquote($argCName);
  933.  
  934.   my $bCustomDefaultHandler = 0;
  935.   my $bNoDefaultHandler = 0;
  936.   my $bCustomCCallback = 0;
  937.   my $bRefreturn = 0;
  938.   
  939.   while(scalar(@args) > 2) # If optional arguments are there.
  940.   {
  941.     my $argRef = string_trim(pop @args);
  942.     if($argRef eq "custom_default_handler")
  943.     {
  944.       $bCustomDefaultHandler = 1;
  945.     }
  946.  
  947.     if($argRef eq "no_default_handler")
  948.     {
  949.       $bNoDefaultHandler = 1;
  950.     }
  951.  
  952.     if($argRef eq "custom_c_callback")
  953.     {
  954.       $bCustomCCallback = 1;
  955.     }
  956.  
  957.     if($argRef eq "refreturn")
  958.     {
  959.       $bRefreturn = 1;
  960.     }
  961.   }
  962.  
  963.  
  964.   $self->output_wrap_signal( $argCppDecl, $argCName, $$self{filename}, $$self{line_num}, $bCustomDefaultHandler, $bNoDefaultHandler, $bCustomCCallback, $bRefreturn);
  965. }
  966.  
  967. # void on_wrap_vfunc()
  968. sub on_wrap_vfunc($)
  969. {
  970.   my ($self) = @_;
  971.  
  972.   if( !($self->check_for_eof()) )
  973.   {
  974.     return;
  975.   }
  976.  
  977.   my $str = $self->extract_bracketed_text();
  978.   my @args = string_split_commas($str);
  979.  
  980.   #Get the arguments:
  981.   my $argCppDecl = $args[0];
  982.   my $argCName = $args[1];
  983.   $argCName = string_trim($argCName);
  984.   $argCName = string_unquote($argCName);
  985.  
  986.   my $refreturn = 0;
  987.   my $refreturn_ctype = 0;
  988.  
  989.   # Extra ref needed?
  990.   while(scalar(@args) > 2) # If the optional ref/err arguments are there.
  991.   {
  992.     my $argRef = string_trim(pop @args);
  993.  
  994.     if($argRef eq "refreturn")
  995.       { $refreturn = 1; }
  996.     elsif($argRef eq "refreturn_ctype")
  997.       { $refreturn_ctype = 1; }
  998.   }
  999.  
  1000.   $self->output_wrap_vfunc($argCppDecl, $argCName, $refreturn, $refreturn_ctype,
  1001.                            $$self{filename}, $$self{line_num});
  1002. }
  1003.  
  1004. sub on_wrap_enum($)
  1005. {
  1006.   my ($self) = @_;
  1007.  
  1008.   return if(!$self->check_for_eof());
  1009.  
  1010.   my $outputter = $$self{objOutputter};
  1011.   my $out = \@{$$outputter{out}};
  1012.  
  1013.   # Look back for a Doxygen comment for this _WRAP_ENUM.  If there is one,
  1014.   # remove it from the output and pass it to the m4 _ENUM macro instead.
  1015.   my $comment = "";
  1016.  
  1017.   if(scalar(@$out) >= 2)
  1018.   {
  1019.     # steal the last two tokens
  1020.     my @back = splice(@$out, -2);
  1021.     local $_ = $back[0];
  1022.  
  1023.     # Check for /*[*!] ... */ or //[/!] comments.  The closing */ _must_
  1024.     # be the last token of the previous line.  Apart from this restriction,
  1025.     # anything else should work, including multi-line comments.
  1026.  
  1027.     if($back[1] eq "\n" && (m#^/\*`[*!](.+)'\*/#s || m#^//`[/!](.+)'$#))
  1028.     {
  1029.       $comment = $1;
  1030.       $comment =~ s/\s+$//;
  1031.     }
  1032.     else
  1033.     {
  1034.       # restore stolen tokens
  1035.       push(@$out, @back);
  1036.     }
  1037.   }
  1038.  
  1039.   # get the arguments
  1040.   my @args = string_split_commas($self->extract_bracketed_text());
  1041.  
  1042.   my $cpp_type = string_trim(shift(@args));
  1043.   my $c_type   = string_trim(shift(@args));
  1044.  
  1045.   # The remaining elements in @args could be flags or s#^FOO_## substitutions.
  1046.  
  1047.   $outputter->output_wrap_enum(
  1048.       $$self{filename}, $$self{line_num}, $cpp_type, $c_type, $comment, @args);
  1049. }
  1050.  
  1051. sub on_wrap_gerror($)
  1052. {
  1053.   my ($self) = @_;
  1054.  
  1055.   return if(!$self->check_for_eof());
  1056.  
  1057.   # get the arguments
  1058.   my @args = string_split_commas($self->extract_bracketed_text());
  1059.  
  1060.   my $cpp_type = string_trim(shift(@args));
  1061.   my $c_enum   = string_trim(shift(@args));
  1062.   my $domain   = string_trim(shift(@args));
  1063.  
  1064.   # The remaining elements in @args could be flags or s#^FOO_## substitutions.
  1065.  
  1066.   $$self{objOutputter}->output_wrap_gerror(
  1067.       $$self{filename}, $$self{line_num}, $cpp_type, $c_enum, $domain, @args);
  1068. }
  1069.  
  1070. sub on_wrap_property($)
  1071. {
  1072.   my ($self) = @_;
  1073.   my $objOutputter = $$self{objOutputter};
  1074.  
  1075.   if( !($self->check_for_eof()) )
  1076.   {
  1077.     return;
  1078.   }
  1079.  
  1080.   my $str = $self->extract_bracketed_text();
  1081.   my @args = string_split_commas($str);
  1082.  
  1083.   #Get the arguments:
  1084.   my $argPropertyName = $args[0];
  1085.   $argPropertyName = string_trim($argPropertyName);
  1086.   $argPropertyName = string_unquote($argPropertyName);
  1087.  
  1088.   #Convert the property name to a canonical form, as it is inside gobject.
  1089.   #Otherwise, gobject might not recognise the name, 
  1090.   #and we will not recognise the property name when we get notification that the value changes.
  1091.   $argPropertyName =~ s/_/-/g; #g means replace all.
  1092.  
  1093.   my $argCppType = $args[1];
  1094.   $argCppType = string_trim($argCppType);
  1095.   $argCppType = string_unquote($argCppType);
  1096.  
  1097.   my $filename = $$self{filename};
  1098.   my $line_num = $$self{line_num};
  1099.  
  1100.   $objOutputter->output_wrap_property($filename, $line_num, $argPropertyName, $argCppType, $$self{c_class});
  1101. }
  1102.  
  1103.  
  1104. sub output_wrap_check($$$$$$)
  1105. {
  1106.   my ($self, $CppDecl, $signal_name, $filename, $line_num, $macro_name) = @_;
  1107.  
  1108.   #Some checks:
  1109.  
  1110.  
  1111.   if (!$$self{in_class})
  1112.   {
  1113.     print STDERR "$filename:$line_num: $macro_name macro encountered outside class\n";
  1114.     return;
  1115.   }
  1116.  
  1117.   if ($CppDecl =~ /^\S+$/ ) #If it's not empty and it contains no whitespace.
  1118.   {
  1119.     print STDERR "$filename:$line_num:$macro_name can't handle unspecified entity $CppDecl\n";
  1120.     return;
  1121.   }
  1122.  
  1123.  
  1124. }
  1125.  
  1126. # void output_wrap($CppDecl, $signal_name, $filename, $line_num, $bCustomDefaultHandler, $bNoDefaultHandler, $bCustomCCallback, $bRefreturn)
  1127. # Also used for vfunc.
  1128. sub output_wrap_signal($$$$$$$$)
  1129. {
  1130.   my ($self, $CppDecl, $signal_name, $filename, $line_num, $bCustomDefaultHandler, $bNoDefaultHandler, $bCustomCCallback, $bRefreturn) = @_;
  1131.   
  1132.   #Some checks:
  1133.   $self->output_wrap_check($CppDecl, $signal_name, $filename, $line_num, "WRAP_SIGNAL");
  1134.  
  1135.   # handle first argument
  1136.  
  1137.   #Parse the method decaration and build an object that holds the details:
  1138.   my $objCppSignal = &Function::new($CppDecl, $self);
  1139.   $$objCppSignal{class} = $$self{class}; #Remember the class name for use in Outputter::output_wrap_signal().
  1140.  
  1141.  
  1142.   # handle second argument:
  1143.   my $objCSignal = undef;
  1144.  
  1145.   my $objOutputter = $$self{objOutputter};
  1146.  
  1147.   #Get the c function's details:
  1148.   if ($signal_name ne "" ) #If it's not empty and it contains no whitespace.
  1149.   {
  1150.     $objCSignal = GtkDefs::lookup_signal($$self{c_class}, $signal_name);
  1151.  
  1152.     # Check for failed lookup.
  1153.     if($objCSignal eq 0) 
  1154.     {
  1155.     print STDERR "$signal_name\n";
  1156.       $objOutputter->output_wrap_failed($signal_name, 
  1157.         " signal defs lookup failed");
  1158.       return;
  1159.     }
  1160.   }
  1161.  
  1162.   $objOutputter->output_wrap_sig_decl($filename, $line_num, $objCSignal, $objCppSignal, $signal_name, $bCustomCCallback);
  1163.  
  1164.   if($bNoDefaultHandler eq 0)
  1165.   {
  1166.     $objOutputter->output_wrap_default_signal_handler_h($filename, $line_num, $objCppSignal, $objCSignal);
  1167.  
  1168.     my $bImplement = 1;
  1169.     if($bCustomDefaultHandler) { $bImplement = 0; }
  1170.     $objOutputter->output_wrap_default_signal_handler_cc($filename, $line_num, $objCppSignal, $objCSignal, $bImplement, $bCustomCCallback, $bRefreturn);
  1171.   }
  1172. }
  1173.  
  1174. # void output_wrap($CppDecl, $signal_name, $filename, $line_num)
  1175. # Also used for vfunc.
  1176. sub output_wrap_vfunc($$$$$$$)
  1177. {
  1178.   my ($self, $CppDecl, $vfunc_name, $refreturn, $refreturn_ctype, $filename, $line_num) = @_;
  1179.  
  1180.   #Some checks:
  1181.   $self->output_wrap_check($CppDecl, $vfunc_name, $filename, $line_num, "VFUNC");
  1182.  
  1183.   # handle first argument
  1184.  
  1185.   #Parse the method decaration and build an object that holds the details:
  1186.   my $objCppVfunc = &Function::new($CppDecl, $self);
  1187.  
  1188.  
  1189.   # handle second argument:
  1190.   my $objCVfunc = undef;
  1191.  
  1192.   my $objOutputter = $$self{objOutputter};
  1193.  
  1194.   #Get the c function's details:
  1195.   if ($vfunc_name =~ /^\S+$/ ) #If it's not empty and it contains no whitespace.
  1196.   {
  1197.     $objCVfunc = GtkDefs::lookup_signal($$self{c_class},$vfunc_name);
  1198.     if(!$objCVfunc) #If the lookup failed:
  1199.     {
  1200.       $objOutputter->output_wrap_failed($vfunc_name, " vfunc defs lookup failed");
  1201.       return;
  1202.     }
  1203.   }
  1204.  
  1205.   # Write out the appropriate macros.
  1206.   # These macros are defined in vfunc.m4:
  1207.  
  1208.   $$objCppVfunc{rettype_needs_ref} = $refreturn;
  1209.   $$objCppVfunc{name} .= "_vfunc"; #All vfuncs should have the "_vfunc" prefix, and a separate easily-named invoker method.
  1210.  
  1211.   $$objCVfunc{rettype_needs_ref} = $refreturn_ctype;
  1212.  
  1213.   $objOutputter->output_wrap_vfunc_h($filename, $line_num, $objCppVfunc, $objCVfunc);
  1214.   $objOutputter->output_wrap_vfunc_cc($filename, $line_num, $objCppVfunc, $objCVfunc);
  1215. }
  1216.  
  1217. # give some sort of weights to sorting attibutes
  1218. sub byattrib() 
  1219. {
  1220.   my %attrib_value = (
  1221.      "virtual_impl" ,1,
  1222.      "virtual_decl" ,2,
  1223.      # "sig_impl"     ,3,
  1224.      "sig_decl"     ,4, 
  1225.      "meth"         ,5
  1226.   );
  1227.  
  1228.   # $a and $b are hidden parameters to a sorting function
  1229.   return $attrib_value{$b} <=> $attrib_value{$a}; 
  1230. }
  1231.  
  1232.  
  1233. # void on_wrap_corba_method()
  1234. sub on_wrap_corba_method($)
  1235. {
  1236.   my ($self) = @_;
  1237.   my $objOutputter = $$self{objOutputter};
  1238.  
  1239.   if( !($self->check_for_eof()) )
  1240.   {
  1241.    return;
  1242.   }
  1243.  
  1244.   my $filename = $$self{filename};
  1245.   my $line_num = $$self{line_num};
  1246.  
  1247.   my $str = $self->extract_bracketed_text();
  1248.   my @args = string_split_commas($str);
  1249.  
  1250.   my $entity_type = "method";
  1251.  
  1252.   if (!$$self{in_class})
  1253.     {
  1254.       print STDERR "$filename:$line_num:_WRAP macro encountered outside class\n";
  1255.       return;
  1256.     }
  1257.  
  1258.   my $objCfunc;
  1259.   my $objCppfunc;
  1260.  
  1261.   # handle first argument
  1262.   my $argCppMethodDecl = $args[0];
  1263.   if ($argCppMethodDecl =~ /^\S+$/ ) #Checks that it's not empty and that it contains no whitespace.
  1264.   {
  1265.     print STDERR "$filename:$line_num:_WRAP can't handle unspecified method $argCppMethodDecl\n";
  1266.     return;
  1267.   }
  1268.   else
  1269.   {
  1270.     #Parse the method decaration and build an object that holds the details:
  1271.     $objCppfunc = &Function::new($argCppMethodDecl, $self);
  1272.   }
  1273.  
  1274.   $objOutputter->output_wrap_corba_method($filename, $line_num, $objCppfunc);
  1275. }
  1276.  
  1277.  
  1278. 1; # return package loaded okay.
  1279.